
import numpy as np

import constantValues as cv
import debugPrinter as dp

from lslReceiver import LSLReceiver
from edfSaver import EDFSaver
import os
import subprocess
from worker import Worker
from setting import SETTING
from dsp.dSPx import DSPx

from udp_server import start_server, send_text_to_all, recv_next, set_on_message
from queue import Empty
import time
import struct

from lslSender import LSLSender



mLSL = LSLSender('dummy')

class DATATOLSL(object):
    """docstring for DATATOLSL"""
    def __init__(self, arg):
        super(DATATOLSL, self).__init__()
        self.arg = arg
        # self.pkg_arr = None
        self.last_pkn = 0
        self.CH_NUM = 4
        self.PKG_DATA_OFFSET = 4

    def new_data_pkg_binary(self,arr):
        # do not deal with the packet loss
        # self.pkg_arr = arr

        if (len(arr))!=812:
            if (len(arr)==18):
                print(arr)
                return
            else:
                print('something wrong, len is :'+str(len(arr)))
                return

        # arr_int = np.zeros((10*3*9))
        for i in range(cv.DATA_LEN_PKG):
            offset_pkg = i*3*9*3

            arr_int =  np.zeros((3*8),dtype = np.int32) # one sample point,with 24 channels 

            for chip_n in range(3):
                offset_pkg_chip = offset_pkg + chip_n*3*9
                for ch in range(1,9): # ignore the 24 status bits
                    tmp = bytearray(4)
                    for t in range(3):
                        tmp[t+1] = arr[offset_pkg_chip+ch*3+t]
                    if tmp[1] & 0x80:
                        tmp[0] = 0xFF
                    else:
                        tmp[0] = 0x00

                    arr_int[chip_n*8+ch-1] = struct.unpack('>i', tmp)[0]
                    # arr_int[i*27+chip_n*9+ch] = struct.unpack('>i', tmp)[0]

            mLSL.send_eeg_mii(arr_int)

        # check the packet number
        tmp_pkg_num = bytearray(2)
        tmp_pkg_num[0] = arr[810]
        tmp_pkg_num[1] = arr[811]

        tmp_pkg = struct.unpack('<H', tmp_pkg_num)[0]
        # print("pkg_num = "+str(tmp_pkg))
        diff_pkg_num = tmp_pkg - self.last_pkn
        if (diff_pkg_num)>1:
            print('packet loss: '+str(diff_pkg_num))
        self.last_pkn = tmp_pkg

        # check some number
        # for i in range(10):
        #     print(arr_int[i])

    def new_data_pkg_binary_bci32(self,arr):

        if (len(arr))!=1086:
            print('something wrong, len is :'+str(len(arr)))
            return

        # check the packet number
        tmp_pkg_num = bytearray(2)
        tmp_pkg_num[0] = arr[2]
        tmp_pkg_num[1] = arr[3]

        pkn = struct.unpack('<H', tmp_pkg_num)[0]

        if(self.last_pkn is None):
            self.last_pkn = pkn
        d = pkn - self.last_pkn - 1

        # dp.dpt(pkn)

        # insert zeros # I do not know how to transfer NAN in lsl, so I use 0 
        if(d>0)&(d<100):
            print('insert zeros')
            # e = np.zeros(shape=(8,), dtype=int)
            # # e[:] = np.nan
            # a = np.zeros(shape=(4,), dtype=int)
            # a[:] = np.nan
            arr_int =  np.zeros((self.CH_NUM*8),dtype = np.int32) # one sample point,with 24 channels 

            for i in range(d): #how many packet lost
                for i in range(cv.DATA_LEN_PKG):
                    mLSL.send_bci32(arr_int)

        self.last_pkn = pkn


        # arr_int = np.zeros((10*3*9))
        for i in range(cv.DATA_LEN_PKG):
            offset_pkg = self.PKG_DATA_OFFSET +i*3*9*self.CH_NUM

            arr_int =  np.zeros((self.CH_NUM*8),dtype = np.int32) # one sample point,with 24 channels 

            for chip_n in range(self.CH_NUM):
                offset_pkg_chip = offset_pkg + chip_n*3*9
                for ch in range(1,9): # ignore the 24 status bits
                    tmp = bytearray(4)
                    for t in range(3):
                        tmp[t+1] = arr[offset_pkg_chip+ch*3+t]
                    if tmp[1] & 0x80:
                        tmp[0] = 0xFF
                    else:
                        tmp[0] = 0x00

                    arr_int[chip_n*8+ch-1] = struct.unpack('>i', tmp)[0]
                    # arr_int[i*27+chip_n*9+ch] = struct.unpack('>i', tmp)[0]

            mLSL.send_bci32(arr_int)







